// 模板方法的核心是封装不变的部分，扩展可变部分
#include <iostream>
#include <string>

class AbstractSegment
{
    public:
    virtual void setInputImage() = 0;
    virtual void preProcessing() = 0;
    virtual void segment() = 0;
    virtual void printResult() = 0;
    void specificMethod(){
        std::cout << "This is a test for lung segment." << std::endl;
    }

    void templateMethod(){
        specificMethod();
        setInputImage();
        preProcessing();
        segment();
        printResult();
    }

    virtual ~AbstractSegment(){};
};

class ThresholdSegment: public AbstractSegment
{
    void setInputImage(){
        std::cout << "The MRI image input finished." << std::endl;
    }

    void preProcessing(){
        std::cout << "Normalize to 0-255." << std::endl;
    }

    void segment(){
        std::cout << "Using threshold to segment." << std::endl;
    }
    
    void printResult(){
        std::cout << "The loss of result is 0.05." << std::endl;
    }

};


class GrowingSegment: public AbstractSegment
{
    void setInputImage(){
        std::cout << "The CT image input finished." << std::endl;
    }

    void preProcessing(){
        std::cout << "Clip image [-400,1600] and normalize to [0,255]" << std::endl;
    }

    void segment(){
        std::cout <<"Using growing up to segment." <<std::endl;
    }
    
    void printResult(){
        std::cout << "The loss of result is 0.01." << std::endl;
    }
};


int main(int argc, char const *argv[])
{
    AbstractSegment* segment = new ThresholdSegment();
    segment->templateMethod();
    delete segment;

    std::cout<<"\n\nChanged alg."<< std::endl;
    segment = new GrowingSegment();
    segment->templateMethod();

    delete segment;

    return 0;
}
